﻿/*

 
参考资料：
[1] .Net4.0并行库介绍——通过TaskFactory.FromAsync简化APM
https://www.cnblogs.com/TianFang/archive/2009/11/07/1597953.html
 
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Verifications.vers
{
    internal class TaskFactoryDemo : VerificationBase
    {

        public override void Test()
        {
            Action threadStart = (() => { });
            WaitCallback waitCallback = new WaitCallback(a => { Debug.WriteLine("a = " + a); });
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Reset();
            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
                ThreadPool.UnsafeQueueUserWorkItem(waitCallback, null);
            }
            stopWatch.Stop();
            Console.WriteLine("{0,-40}{1}", "ThreadPool.UnsafeQueueUserWorkItem():", stopWatch.ElapsedMilliseconds);
            GC.Collect();

            stopWatch.Reset();
            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
                System.Threading.ThreadPool.QueueUserWorkItem(waitCallback);
            }
            stopWatch.Stop();
            Console.WriteLine("{0,-40}{1}", "ThreadPool.QueueUserWorkItem():", stopWatch.ElapsedMilliseconds);
            GC.Collect();

            stopWatch.Reset();
            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
                Task t = new Task(threadStart);
                t.Start();
            }
            stopWatch.Stop();
            Console.WriteLine("{0,-40}{1}", "Task():", stopWatch.ElapsedMilliseconds);
            GC.Collect();

            stopWatch.Reset();

            //stopWatch.Start();
            //for (int i = 0; i < 10000; i++)
            //{
            //    threadStart.BeginInvoke(null, null);
            //}
            //stopWatch.Stop();
            //Console.WriteLine("{0,-40}{1}", "Delegate.BeinInvoke():", stopWatch.ElapsedTicks); 
        }

        public void Test1()
        {
            var del = new Func<string, string>(doo);
            var obj = new object();
            // System.PlatformNotSupportedException:“Operation is not supported on this platform.”

            // del.BeginInvoke((s1, s2, s3, o, state) => { Debug.WriteLine("done."); });

            var task = Task<string>.Factory.FromAsync(del.BeginInvoke, del.EndInvoke, "a1", obj)
            .ContinueWith(t =>
            {
                WriteLog($"执行doo的返回值：{t.Result}", "test2");
                WriteLog("执行doo的Over", "test2");
            });

            WriteLog("go next", "test");

            var arrFriends = new List<int>();
            arrFriends.Add(1);
            arrFriends.Add(200);
            arrFriends.Add(30);
            arrFriends.Sort();

            string s = "";
            Array.ForEach(arrFriends.ToArray(), i => s += (s != "" ? "," : "") + i);

            WriteLog("结果：" + s, "test");
        }

        //异步执行方法
        private string doo(string a)
        {
            WriteLog("a = " + a, "test1");
            return "res=" + a;
        }

        private void WriteLog(string message, string category)
        {
            Debug.WriteLine($"{category}: {message}");
        }

        public IEnumerable<Task> CopyStreamAsync(string? inputfile, string? outputfile)
        {
            if (!File.Exists(inputfile))
            {
                yield return null;
            }

            var buffer = new byte[0x2000];
            using (Stream input = new FileStream(inputfile, FileMode.Open, FileAccess.Read))
            {
                using (Stream output = new FileStream(outputfile, FileMode.Create, FileAccess.Write))
                {
                    while (true)
                    {
                        var readTask = Task<int>.Factory.FromAsync(input.BeginRead, input.EndRead, buffer, 0, buffer.Length, null);
                        yield return readTask;

                        if (readTask.Result == 0)
                            break;

                        yield return Task.Factory.FromAsync(output.BeginWrite, output.EndWrite, buffer, 0, buffer.Length, null);
                    }
                }
            }

        }

    }
}
